/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ugc.cnel.manabi.jpa;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import org.ugc.cnel.manabi.entidades.Ciudad;
import org.ugc.cnel.manabi.entidades.Cliente;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Vector;
import org.ugc.cnel.manabi.jpa.exceptions.IllegalOrphanException;
import org.ugc.cnel.manabi.jpa.exceptions.NonexistentEntityException;
import org.ugc.cnel.manabi.jpa.exceptions.PreexistingEntityException;

/**
 *
 * @author Admin
 */
public class CiudadJpaController {

    public CiudadJpaController() {
        emf = Persistence.createEntityManagerFactory("SICOPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    /**
     * Metodo Obsoleto
     * @param ciudad
     * @throws PreexistingEntityException
     * @throws Exception
     * @deprecated por itegracion con SICO
     */
    @Deprecated
    public void create(Ciudad ciudad) throws PreexistingEntityException, Exception {
        if (ciudad.getClienteCollection() == null) {
            ciudad.setClienteCollection(new ArrayList<Cliente>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<Cliente> attachedClienteCollection = new ArrayList<Cliente>();
            for (Cliente clienteCollectionClienteToAttach : ciudad.getClienteCollection()) {
                clienteCollectionClienteToAttach = em.getReference(clienteCollectionClienteToAttach.getClass(), clienteCollectionClienteToAttach.getId());
                attachedClienteCollection.add(clienteCollectionClienteToAttach);
            }
            ciudad.setClienteCollection(attachedClienteCollection);
            em.persist(ciudad);
            /*for (Cliente clienteCollectionCliente : ciudad.getClienteCollection()) {
                Ciudad oldIdCiudadOfClienteCollectionCliente = clienteCollectionCliente.getIdCiudad();
                clienteCollectionCliente.setIdCiudad(ciudad);
                clienteCollectionCliente = em.merge(clienteCollectionCliente);
                if (oldIdCiudadOfClienteCollectionCliente != null) {
                    oldIdCiudadOfClienteCollectionCliente.getClienteCollection().remove(clienteCollectionCliente);
                    oldIdCiudadOfClienteCollectionCliente = em.merge(oldIdCiudadOfClienteCollectionCliente);
                }
            }*/
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findCiudad(ciudad.getId()) != null) {
                throw new PreexistingEntityException("Ciudad " + ciudad + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    /**
     * Metodo Obsoleto
     * @param ciudad
     * @throws IllegalOrphanException
     * @throws NonexistentEntityException
     * @throws Exception
     * @deprecated Integracion SICO
     */
    @Deprecated
    public void edit(Ciudad ciudad) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Ciudad persistentCiudad = em.find(Ciudad.class, ciudad.getId());
            Collection<Cliente> clienteCollectionOld = persistentCiudad.getClienteCollection();
            Collection<Cliente> clienteCollectionNew = ciudad.getClienteCollection();
            List<String> illegalOrphanMessages = null;
            if (clienteCollectionNew != null) {
                for (Cliente clienteCollectionOldCliente : clienteCollectionOld) {
                    if (!clienteCollectionNew.contains(clienteCollectionOldCliente)) {
                        if (illegalOrphanMessages == null) {
                            illegalOrphanMessages = new ArrayList<String>();
                        }
                        illegalOrphanMessages.add("You must retain Cliente " + clienteCollectionOldCliente + " since its idCiudad field is not nullable.");
                    }
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Cliente> attachedClienteCollectionNew = new ArrayList<Cliente>();
            if (clienteCollectionNew != null) {
                for (Cliente clienteCollectionNewClienteToAttach : clienteCollectionNew) {
                    clienteCollectionNewClienteToAttach = em.getReference(clienteCollectionNewClienteToAttach.getClass(), clienteCollectionNewClienteToAttach.getId());
                    attachedClienteCollectionNew.add(clienteCollectionNewClienteToAttach);
                }
            }
            clienteCollectionNew = attachedClienteCollectionNew;
            ciudad.setClienteCollection(clienteCollectionNew);
            ciudad = em.merge(ciudad);
            /*for (Cliente clienteCollectionNewCliente : clienteCollectionNew) {
                if (!clienteCollectionOld.contains(clienteCollectionNewCliente)) {
                    Ciudad oldIdCiudadOfClienteCollectionNewCliente = clienteCollectionNewCliente.getIdCiudad();
                    clienteCollectionNewCliente.setIdCiudad(ciudad);
                    clienteCollectionNewCliente = em.merge(clienteCollectionNewCliente);
                    if (oldIdCiudadOfClienteCollectionNewCliente != null && !oldIdCiudadOfClienteCollectionNewCliente.equals(ciudad)) {
                        oldIdCiudadOfClienteCollectionNewCliente.getClienteCollection().remove(clienteCollectionNewCliente);
                        oldIdCiudadOfClienteCollectionNewCliente = em.merge(oldIdCiudadOfClienteCollectionNewCliente);
                    }
                }
            }*/
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = ciudad.getId();
                if (findCiudad(id) == null) {
                    throw new NonexistentEntityException("The ciudad with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    /**
     * Metodo Obsoleto por Integracion SICO
     * @param id
     * @throws IllegalOrphanException
     * @throws NonexistentEntityException
     * @deprecated
     */
    @Deprecated
    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Ciudad ciudad;
            try {
                ciudad = em.getReference(Ciudad.class, id);
                ciudad.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The ciudad with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Cliente> clienteCollectionOrphanCheck = ciudad.getClienteCollection();
            for (Cliente clienteCollectionOrphanCheckCliente : clienteCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Ciudad (" + ciudad + ") cannot be destroyed since the Cliente " + clienteCollectionOrphanCheckCliente + " in its clienteCollection field has a non-nullable idCiudad field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(ciudad);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Ciudad> findCiudadEntities() {
        return findCiudadEntities(true, -1, -1);
    }

    public List<Ciudad> findCiudadEntities(int maxResults, int firstResult) {
        return findCiudadEntities(false, maxResults, firstResult);
    }

    private List<Ciudad> findCiudadEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            //Query q = em.createQuery("select object(o) from Ciudad as o");
            Query q = em.createNativeQuery("select cast(cancod as int) id,candes nombre,cast(prvcod as int) id_provincia, 13 codigo_provincia from sicod.canton");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            List<Ciudad> lista = new ArrayList<Ciudad>();

            for (Object ciudad : q.getResultList()) {
                Vector vc = (Vector) ciudad;
                int id = Integer.valueOf(vc.get(0).toString());
                String nombre = vc.get(1).toString();
                int id_provincia = Integer.valueOf(vc.get(2).toString());
                int cod_provincia = Integer.valueOf(vc.get(3).toString());
                Ciudad ciu = new Ciudad(id, nombre, id_provincia);
                ciu.setCodigoProvincia(cod_provincia);
                lista.add(ciu);
            }

            //return q.getResultList();
            return lista;
        } finally {
            em.close();
        }
    }

    public Ciudad findCiudad(Integer id) {
        EntityManager em = getEntityManager();
        try {
            Vector vec = (Vector) em.createNativeQuery("select cast(cancod as int) id,candes nombre,cast(prvcod as int) id_provincia, 13 codigo_provincia from sicod.canton where cast(cancod as int)=?1").setParameter(1, id).getSingleResult();
            Ciudad ciudad = null;
            if (vec.size() > 0) {
                ciudad = new Ciudad(Integer.parseInt(vec.get(0).toString()), vec.get(1).toString(), Integer.parseInt(vec.get(2).toString()));
            }
            return ciudad;
        } finally {
            em.close();
        }
    }

    public int getCiudadCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createNativeQuery("select count(*) rows from sicod.CANTON").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
}
